Ein Teil der Kommandos
kann als Sequenz in die
Displaylist geschrieben werden.
Dieses beschleunigt dann die
statischen Szenen, da die
Objektbeschreibungen schon
in ihr vorliegen. Ansonsten geht
es zuerst in den Evaluator,
dieser berechnet alle
polynomialen Kommandos der Eingabe.
Zur Eingabe gelangen Vertices,
welche hauptsaechlich mit Texturen
und Farbwerten verknuepft sind.
Dann geht es weiter mit den
Operationen
auf den Vertices, hier z. B. T&L
oder Vertexshader moeglich, nebenbei
werden die Texturen verarbeitet.
Die dann entstandenen Primitives
werden dann geclippt, und auf eine
Ebene projeziert, man erhaelt 2-D
Fragmente. Auf diesen koennen
dann noch Operationen ausgefuehrt
werden, bevor sie dann als Pixel in den
Framebuffer und zur Ausgabe auf den
Bildschirm gelangen. Auch hier bei
OpenGL ist der Einsatz der Pixelshader
moeglich.
Unten folgt noch ein Stueck
Beispielcode in C++ mit OpenGL.
#include
<windows.h>
#include
<stdlib.h>
#include
<stdio.h>
#include
<math.h>
#include
<gl\gl.h>
#include
<gl\glu.h>
#include
"TEffect.h"
#include
"TTimer.h"
char
szAppName[] = "Framework";
bool
g_bReady;
unsigned
int
g_dwWindowWidth;
unsigned
int
g_dwWindowHeight;
TTimer
g_cTimer;
TEffect*
g_pEffect;
LRESULT
CALLBACK SkeletonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void SetDCPixelFormat(HDC hDC)
{
int
nPixelFormat;
static
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
GetDeviceCaps(hDC,
BITSPIXEL),
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
nPixelFormat = ChoosePixelFormat(hDC,
&pfd);
SetPixelFormat(hDC, nPixelFormat, &pfd);
return;
}
void
ChangeSize(GLsizei w, GLsizei h)
{
if (h == 0)
h = 1;
glViewport( 0, 0, w, h);
}
int
APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
g_bReady = false;
WNDCLASS wc;
HWND hWnd;
wc.style = CS_HREDRAW | CS_VREDRAW |
CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)SkeletonProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL,
IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName
= NULL;
wc.lpszClassName
= szAppName;
if (RegisterClass(&wc) == 0)
{
return FALSE;
}
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
640, 480,
NULL, NULL,
hInstance,
NULL);
if (hWnd == NULL)
{
return FALSE;
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
g_bReady = true;
BOOL bGotMsg;
MSG
msg;
// Initialisiere benötigten Klassen
g_cTimer.Init();
g_pEffect = new TEffect(&g_cTimer);
g_pEffect->Init();
PeekMessage(&msg, NULL, 0U, 0U,
PM_NOREMOVE);
while (WM_QUIT != msg.message)
{
bGotMsg =
PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
if (bGotMsg)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
InvalidateRect(hWnd,
NULL, FALSE);
}
}
//
Speicher wieder freigeben, weil die Anwendung beendet wird.
g_pEffect->Release();
delete g_pEffect;
g_bReady = false;
return msg.wParam;
}
LRESULT
CALLBACK SkeletonProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC;
static HDC hDC;
switch (uMsg)
{
case WM_CREATE :
hDC = GetDC(hWnd);
SetDCPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
break;
case WM_KEYDOWN :
if (wParam == VK_ESCAPE)
{
DestroyWindow(hWnd);
}
break;
case WM_DESTROY :
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
break;
case WM_SIZE :
g_dwWindowWidth =
LOWORD(lParam);
g_dwWindowHeight =
HIWORD(lParam);
ChangeSize(g_dwWindowWidth,
g_dwWindowHeight);
break;
case WM_PAINT :
if (g_bReady)
{
g_cTimer.Update();
g_pEffect->Render();
SwapBuffers(hDC);
ValidateRect(hWnd,
NULL);
}
break;
default :
return DefWindowProc(hWnd,
uMsg, wParam, lParam);
}
return
0;
}